package com.ezlcp.user.controller;

import com.alibaba.fastjson2.JSON;
import com.ezlcp.commons.base.db.BaseService;
import com.ezlcp.commons.base.entity.JsonPageResult;
import com.ezlcp.commons.base.entity.JsonResult;
import com.ezlcp.commons.base.search.QueryFilter;
import com.ezlcp.commons.constant.StatusEnum;
import com.ezlcp.commons.tool.Encrypt;
import com.ezlcp.commons.utils.ContextUtil;
import com.ezlcp.commons.utils.TokenUtil;
import com.ezlcp.user.entity.Company;
import com.ezlcp.user.entity.Group;
import com.ezlcp.user.entity.User;
import com.ezlcp.user.enums.ClientTypeEnum;
import com.ezlcp.user.service.CompanyServiceImpl;
import com.ezlcp.user.service.GroupServiceImpl;
import com.ezlcp.user.service.UserServiceImpl;
import com.ezlcp.user.task.RefreshOnlineUserTask;
import com.ezlcp.user.web.BaseController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/ezlcp/user/user")
@Tag(name = "用户表")
public class UserController extends BaseController<User> {
    @Resource
    UserServiceImpl userService;
    @Lazy
    @Autowired
    CompanyServiceImpl companyService;
    @Resource
    GroupServiceImpl groupService;

    @Override
    public BaseService getBaseService() {
        return userService;
    }

    @Override
    protected void handleFilter(QueryFilter filter) {
        String tenantId = ContextUtil.getCurrentTenantId();
        if (StringUtils.isNotEmpty(tenantId)) {
            filter.addQueryParam("Q_tenant_id_S_EQ", tenantId);
        } else {
            filter.addQueryParam("Q_tenant_id_S_ISNULL", "1");
        }
        filter.addQueryParam("Q_status_S_NEQ", "deleted");
    }

    @Operation(summary = "根据当前公司ID查询所有员工")
    @PostMapping("/getByTenantId")
    public JsonResult getByTenantId() {
        if (StringUtils.isEmpty(ContextUtil.getCurrentTenantId())) {
            logService.saveSystemLog(getComment(), "非法操作", null, null);
            return JsonResult.getFailResult("common.insufficientPrivileges");
        }
        logService.saveSystemLog(getComment(), "getByTenantId", null, null);
        return JsonResult.getSuccessResult(userService.getByTenantId(), "common.selSuccess");
    }

    @Operation(summary = "新建员工")
    @PostMapping("/registerUser")
    public JsonResult registerUser(@RequestBody User user) {
        if (userService.checkName(user.getUserName())) {
            return JsonResult.getFailResult("user.userAlreadyExist");
        }
        var curUser = ContextUtil.getCurrentUser();
        user.setTenantId(curUser.getTenantId());
        String checkUserField = userService.checkUserField(user, 0);
        if (checkUserField.length() > 0) {
            return JsonResult.Fail(checkUserField);
        }
        if (user.isTenantUser()) {
            Company company = companyService.getById(curUser.getTenantId());
            Long countStaff = userService.countStaff(curUser.getTenantId());
            if (countStaff >= company.getAccountLimit()) {
                return JsonResult.getFailResult("user.userExceed");
            }

        }
        User newUser = userService.registerUser(user);
        logService.saveSystemLog(getComment(), "registerUser", newUser.getPkId(), JSON.toJSONString(newUser));
        JsonResult result = JsonResult.getSuccessResult("common.handleSuccess");
        result.setData(newUser);
        return result;
    }

    @Operation(summary = "注册公司", description = "根据提交的业务JSON数据保存业务数据记录")
    @PostMapping("/registerCompany")
    public JsonResult registerCompany(@RequestBody Company company) {
        var curUser = ContextUtil.getCurrentUser();
        if (curUser.isTenantUser()) {
            logService.saveSystemLog(getComment(), "非法操作", null, null);
            return JsonResult.getFailResult("common.insufficientPrivileges");
        }
        String checkCompanyField = userService.checkCompanyField(company);
        if (checkCompanyField.length() > 0) {
            return JsonResult.Fail(checkCompanyField);
        }
        if (userService.checkName(company.getUserName())) {
            return JsonResult.Fail("user.userAlreadyExist");
        }
        userService.registerCompany(company);
        return JsonResult.Success("user.loginSuccess");
    }

    @Operation(summary = "修改用户资料")
    @PostMapping("/updateUser")
    public JsonResult updateUser(@RequestBody User user) {
        Integer integer = 0;
        if (user.isStaff()) {
            integer = 1;
        }
        String checkUserField = userService.checkUserField(user, integer);
        if (checkUserField.length() > 0) {
            return JsonResult.Fail(checkUserField);
        }
        User oldEnt = userService.getById(user.getUserId());
        if (!oldEnt.getSeq().equals(user.getSeq())) {
            return JsonResult.Fail("common.dataChange");
        }
        //记录日志
        String detail = "old:" + JSON.toJSONString(oldEnt) + ",new:" + JSON.toJSONString(user);
        user.setSeq(user.getSeq() + 1);
        Boolean updateStatus = userService.updateUser(user, true);
        logService.saveSystemLog(getComment(), "updateUser", user.getPkId(), detail);
        return updateStatus ? JsonResult.Success("user.updateSuccess") : JsonResult.Fail("user.userAlreadyExist");
    }

    @Operation(summary = "修改用戶語言")
    @PostMapping("updateUserLanguage")
    public JsonResult updateUserLanguage(@Parameter(description = "预设语言") @RequestParam(value = "language") String language,
                                         @Parameter(description = "被修改人id") @RequestParam(value = "userId") String userId) {

        if (StringUtils.isEmpty(language)) {
            return JsonResult.Fail("user.inputLanguage");
        }
        if (StringUtils.isEmpty(userId)) {
            return JsonResult.Fail("user.inputUserId");
        }
        User user = userService.getById(userId);
        user.setLanguage(language);
        user.setSeq(user.getSeq() + 1);
        userService.updateById(user);
        return JsonResult.getSuccessResult(user.getLanguage(), "user.updLanguageSuccess");
    }

    @Operation(summary = "个人中心修改密码")
    @PostMapping("updatePassWord")
    public JsonResult updatePassWord(@Parameter(description = "原始密碼") @RequestParam(value = "oldPassword") String oldPassword,
                                     @Parameter(description = "新密碼") @RequestParam(value = "newPassword") String newPassword) {
        User user = userService.getById(ContextUtil.getCurrentUserId());
        if (StringUtils.isEmpty(oldPassword)) {
            return JsonResult.Fail("user.inputOldPassword");
        }
        if (StringUtils.isEmpty(newPassword)) {
            return JsonResult.Fail("user.inputNewPassword");
        }
        String userId = user.getUserId();
        //校验密码
        String encPw = Encrypt.getMd5Password(userId, oldPassword);
        if (!encPw.equals(user.getPassword())) {
            return JsonResult.Fail("user.oldPasswordError");
        }
        String newPw = Encrypt.getMd5Password(userId, newPassword);
        user.setPassword(newPw);
        user.setSeq(user.getSeq() + 1);
        userService.update(user);
        //记录日志
        String detail = "old:" + user.getPassword() + ",new:" + newPw;
        logService.saveSystemLog(getComment(), "updatePassWord", user.getPkId(), detail);
        return JsonResult.Success("user.updPasswordSuccess");
    }

    @Operation(summary = "上级修改下级密码")
    @PostMapping("updateLowerPassWord")
    public JsonResult updatesLowerPassWord(@Parameter(description = "新密碼") @RequestParam(value = "newPassword") String newPassword,
                                           @Parameter(description = "被修改人id") @RequestParam(value = "userId") String userId) {
        String msg = userService.updatesLowerPassWord(newPassword, userId);
        if (msg.length() > 0) {
            return JsonResult.getFailResult(msg);
        }
        return JsonResult.Success("user.updPasswordSuccess");
    }

    @Override
    @Operation(summary = "根据主键ID删除记录", description = "根据主键ID删除记录")
    @PostMapping("del")
    public JsonResult del(@RequestParam(value = "userId") String userId) {
        if (StringUtils.isEmpty(userId)) {
            return JsonResult.getFailResult("user.userIdNotNull");
        }
        User user = userService.getById(userId);
        user.setStatus(StatusEnum.deleted.name());
        user.setSeq(user.getSeq() + 1);
        userService.update(user);
        logService.saveSystemLog(getComment(), "delete", user.getPkId(), null);
        return JsonResult.Success("common.delSuccess");
    }

    @Override
    @Operation(summary = "【已关闭】查询当前业务表的所有数据", description = "查询当前实体表的所有数据。")
    public JsonPageResult getAll() {
        return null;
    }

    @Override
    @Operation(summary = "【已关闭】保存业务数据记录", description = "根据提交的业务JSON数据保存业务数据记录")
    public JsonResult save(User entity, BindingResult validResult) {
        return null;
    }

    /**
     * @description: 覆盖查询用户详细，返回用户的角色信息
     * @author Elwin ZHANG
     * @date 2022/6/15 13:38
     */
    @Override
    public JsonResult<User> get(String pkId) {
        JsonResult result = super.get(pkId);
        User user = (User) result.getData();
        if (user == null) {
            return result;
        }
        //查询用户角色
        var groups = groupService.getUserGroups(user.getUserId());
        String[] arrIds = new String[]{};
        if (groups != null && groups.size() != 0) {
            List<String> listRoleIds = groups.stream().map(Group::getGroupId).collect(Collectors.toList());
            arrIds = listRoleIds.toArray(arrIds);
        }
        user.setGroupIds(arrIds);
        return result;
    }

    @Operation(summary = "查询公司的在线用户")
    @GetMapping("/getOnlineUsers")
    public JsonResult getOnlineUsers() {
        var result = JsonResult.getSuccessResult("common.handleSuccess");
        var data = TokenUtil.getOnlineUsers(ContextUtil.getCurrentTenantId());
        result.setData(data);
        return result;
    }

    @Operation(summary = "强制下线某用户")
    @PostMapping("/forcedOffline")
    public JsonResult forcedOffline(@Parameter(description = "用户ID") @RequestParam(value = "userId") String userId) {
        if (StringUtils.isEmpty(userId)) {
            //参数不正确
            return JsonResult.Fail("common.paramError");
        }
        var user = this.userService.getById(userId);
        if (user == null) {
            return JsonResult.Fail("common.paramError");
        }
        if (StringUtils.compare(user.getTenantId(), ContextUtil.getCurrentTenantId()) != 0) {
            //不能操作非本公司记录
            return JsonResult.Fail("common.noHandle");
        }
        //删除该用户TOKEN，并重新统计在线用户
        RefreshOnlineUserTask.groupTokenByTenantId(userId);
        logService.logOut(userId, ClientTypeEnum.PC.getValue());
        logService.saveSystemLog(getComment(), "force offline", userId, userId);
        return JsonResult.Success("common.handleSuccess");
    }

    @Override
    public String getComment() {
        return "用户管理";
    }
}